using System;
using System.IO;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Globalization;

namespace WebChart
{
	[DefaultProperty("Color"), PersistenceMode(PersistenceMode.InnerProperty), TypeConverter(typeof(ExpandableObjectConverter))]
	public class ChartInterior
	{
		// Fields
		private float angle;
		private Color centerColor;
		private Point centerPoint;
		private Color color;
		private Point endPoint;
		private Color foreColor;
		private HatchStyle hatchStyle;
		private System.Drawing.Image image;
		private string imageUrl;
		private LinearGradientMode linearGradientMode;
		private GraphicsPath path;
		private Point startPoint;
		private Color[] surroundColors;
		private InteriorType type;
		private WrapMode wrapMode;

		// Methods
		public ChartInterior()
		{
			this.type = InteriorType.Solid;
			this.color = Color.White;
			this.hatchStyle = HatchStyle.Shingle;
			this.foreColor = Color.Black;
			this.angle = 0f;
			this.linearGradientMode = LinearGradientMode.Horizontal;
			this.centerColor = Color.White;
			this.image = null;
			this.imageUrl = "";
			this.wrapMode = WrapMode.Tile;
			this.startPoint = new Point(0, 0);
			this.endPoint = new Point(100, 100);
		}

		public ChartInterior(Color color) : this()
		{
			this.Color = color;
		}

		private Uri CalculateUri(string path)
		{
			try
			{
				return new Uri(path);
			}
			catch (UriFormatException)
			{
				path = System.IO.Path.GetFullPath(path);
				return new Uri(path);
			}
		}

		public Brush GetBrush(Graphics graphics)
		{
			switch (this.type)
			{
				case InteriorType.Solid:
					return new SolidBrush(graphics.GetNearestColor(this.color));

				case InteriorType.Hatch:
					return new HatchBrush(this.HatchStyle, graphics.GetNearestColor(this.foreColor), graphics.GetNearestColor(this.color));

				case InteriorType.LinearGradient:
					return new LinearGradientBrush(new Rectangle(this.StartPoint.X, this.StartPoint.Y, this.EndPoint.X - this.StartPoint.X, this.EndPoint.Y - this.StartPoint.Y), this.color, this.foreColor, this.Angle, true);

				case InteriorType.PathGradient:
				{
					PathGradientBrush brush = new PathGradientBrush(this.Path);
					brush.WrapMode = this.WrapMode;
					brush.SurroundColors = this.SurroundColors;
					brush.CenterPoint = (PointF) this.CenterPoint;
					brush.CenterColor = this.CenterColor;
					return brush;
				}
				case InteriorType.Texture:
				{
					if (this.Image != null)
					{
						return new TextureBrush(this.Image, this.WrapMode);
					}
					FileInfo info = new FileInfo(this.imageUrl);
					if (!info.Exists)
					{
						info = new FileInfo(this.CalculateUri(this.imageUrl).AbsolutePath);
						if (!info.Exists)
						{
							throw new FileLoadException("The file: " + this.imageUrl + " could not be found.");
						}
					}
					return new TextureBrush(new Bitmap(info.FullName), this.WrapMode);
				}
			}
			return null;
		}

		public override string ToString()
		{
			return string.Format(CultureInfo.InvariantCulture, "{0}-{1}", new object[] { this.type.ToString(CultureInfo.InvariantCulture), this.color.Name });
		}

		// Properties
		[NotifyParentProperty(true), DefaultValue((float) 0f)]
		public float Angle
		{
			get
			{
				return this.angle;
			}
			set
			{
				this.angle = value;
			}
		}

		[DefaultValue(typeof(Color), "White"), NotifyParentProperty(true)]
		public Color CenterColor
		{
			get
			{
				return this.centerColor;
			}
			set
			{
				this.centerColor = value;
			}
		}

		[NotifyParentProperty(true), DefaultValue(typeof(Point), "0,0")]
		public Point CenterPoint
		{
			get
			{
				return this.centerPoint;
			}
			set
			{
				this.centerPoint = value;
			}
		}

		[DefaultValue(typeof(Color), "White"), TypeConverter(typeof(WebColorConverter)), NotifyParentProperty(true)]
		public Color Color
		{
			get
			{
				return this.color;
			}
			set
			{
				this.color = value;
			}
		}

		[DefaultValue(typeof(Point), "100,100"), NotifyParentProperty(true)]
		public Point EndPoint
		{
			get
			{
				return this.endPoint;
			}
			set
			{
				this.endPoint = value;
			}
		}

		[TypeConverter(typeof(WebColorConverter)), DefaultValue(typeof(Color), "Black"), NotifyParentProperty(true)]
		public Color ForeColor
		{
			get
			{
				return this.foreColor;
			}
			set
			{
				this.foreColor = value;
			}
		}

		[DefaultValue(0x2d), NotifyParentProperty(true)]
		public HatchStyle HatchStyle
		{
			get
			{
				return this.hatchStyle;
			}
			set
			{
				this.hatchStyle = value;
			}
		}

		public System.Drawing.Image Image
		{
			get
			{
				return this.image;
			}
			set
			{
				this.image = value;
			}
		}

		[NotifyParentProperty(true), Editor("System.Windows.Forms.Design.FileNameEditor, System.Design", typeof(UITypeEditor)), DefaultValue(""), Category("Appearance")]
		public string ImageUrl
		{
			get
			{
				return this.imageUrl;
			}
			set
			{
				this.imageUrl = value;
			}
		}

		[NotifyParentProperty(true), DefaultValue(0)]
		public LinearGradientMode LinearGradientMode
		{
			get
			{
				return this.linearGradientMode;
			}
			set
			{
				this.linearGradientMode = value;
			}
		}

		public GraphicsPath Path
		{
			get
			{
				return this.path;
			}
			set
			{
				this.path = value;
			}
		}

		[NotifyParentProperty(true), DefaultValue(typeof(Point), "0,0")]
		public Point StartPoint
		{
			get
			{
				return this.startPoint;
			}
			set
			{
				this.startPoint = value;
			}
		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public Color[] SurroundColors
		{
			get
			{
				return this.surroundColors;
			}
			set
			{
				this.surroundColors = value;
			}
		}

		[DefaultValue(0), NotifyParentProperty(true)]
		public InteriorType Type
		{
			get
			{
				return this.type;
			}
			set
			{
				this.type = value;
			}
		}

		[NotifyParentProperty(true), DefaultValue(0)]
		public WrapMode WrapMode
		{
			get
			{
				return this.wrapMode;
			}
			set
			{
				this.wrapMode = value;
			}
		}
	}
}
